///*
// *  Copyright 2020-2021 Li Fei
// *
// *  Licensed under the Apache License, Version 2.0 (the "License");
// *  you may not use this file except in compliance with the License.
// *  You may obtain a copy of the License at
// *
// *  http://www.apache.org/licenses/LICENSE-2.0
// *
// *  Unless required by applicable law or agreed to in writing, software
// *  distributed under the License is distributed on an "AS IS" BASIS,
// *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// *  See the License for the specific language governing permissions and
// *  limitations under the License.
// */
//package com.pengshun.modules.security.security;
//
//import cn.hutool.core.date.DateField;
//import cn.hutool.core.date.DateUtil;
//import cn.hutool.core.util.IdUtil;
//import cn.hutool.core.util.ObjectUtil;
//import io.jsonwebtoken.*;
//import io.jsonwebtoken.io.Decoders;
////import io.jsonwebtoken.security.Keys;
//import lombok.extern.slf4j.Slf4j;
//import com.pengshun.modules.security.config.bean.SecurityProperties;
//import com.pengshun.utils.RedisUtils;
//import org.springframework.beans.factory.InitializingBean;
//import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
//import org.springframework.security.core.Authentication;
//import org.springframework.security.core.GrantedAuthority;
//import org.springframework.security.core.authority.SimpleGrantedAuthority;
//import org.springframework.security.core.userdetails.User;
//import org.springframework.stereotype.Component;
//
//import javax.servlet.http.HttpServletRequest;
//import java.security.Key;
//import java.util.Arrays;
//import java.util.Collection;
//import java.util.Collections;
//import java.util.Date;
//import java.util.concurrent.TimeUnit;
//import java.util.stream.Collectors;
//
///**
// * @author Li Fei
// */
//@Slf4j
//@Component
//public class TokenProvider implements InitializingBean {
//
//    private final SecurityProperties properties;
//    private final RedisUtils redisUtils;
//    public static final String AUTHORITIES_KEY = "auth";
//    private JwtParser jwtParser;
//    private JwtBuilder jwtBuilder;
//
//    public TokenProvider(SecurityProperties properties, RedisUtils redisUtils) {
//        this.properties = properties;
//        this.redisUtils = redisUtils;
//    }
//
//    @Override
//    public void afterPropertiesSet() {
//        byte[] keyBytes = Decoders.BASE64.decode(properties.getBase64Secret());
//        Key key = Keys.hmacShaKeyFor(keyBytes);
//        jwtParser = Jwts.parserBuilder()
//                .setSigningKey(key)
//                .build();
//        jwtBuilder = Jwts.builder()
//                .signWith(key, SignatureAlgorithm.HS512);
//    }
//
//    /**
//     * 创建Token 设置永不过期，
//     * Token 的时间有效性转到Redis 维护
//     *
//     * @param authentication /
//     * @return /
//     */
//    public String createToken(Authentication authentication) {
//        /*
//         * 获取权限列表
//         */
//        String authorities = authentication.getAuthorities().stream()
//                .map(GrantedAuthority::getAuthority)
//                .collect(Collectors.joining(","));
//
//        return jwtBuilder
//                // 加入ID确保生成的 Token 都不一致
//                .setId(IdUtil.simpleUUID())
//                .claim(AUTHORITIES_KEY, authorities)
//                .setSubject(authentication.getName())
//                .compact();
//    }
//
//    /**
//     * 依据Token 获取鉴权信息
//     *
//     * @param token /
//     * @return /
//     */
//    Authentication getAuthentication(String token) {
//        Claims claims = getClaims(token);
//
//        // fix bug: 当前用户如果没有任何权限时，在输入用户名后，刷新验证码会抛IllegalArgumentException
//        Object authoritiesStr = claims.get(AUTHORITIES_KEY);
//        Collection<? extends GrantedAuthority> authorities =
//                ObjectUtil.isNotEmpty(authoritiesStr) ?
//                        Arrays.stream(authoritiesStr.toString().split(","))
//                                .map(SimpleGrantedAuthority::new)
//                                .collect(Collectors.toList()) : Collections.emptyList();
//        User principal = new User(claims.getSubject(), "******", authorities);
//        return new UsernamePasswordAuthenticationToken(principal, token, authorities);
//    }
//
//    public Claims getClaims(String token) {
//        return jwtParser
//                .parseClaimsJws(token)
//                .getBody();
//    }
//
//    /**
//     * @param token 需要检查的token
//     */
//    public void checkRenewal(String token) {
//        // 判断是否续期token,计算token的过期时间
//        long time = redisUtils.getExpire(properties.getOnlineKey() + token) * 1000;
//        Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time);
//        // 判断当前时间与过期时间的时间差
//        long differ = expireDate.getTime() - System.currentTimeMillis();
//        // 如果在续期检查的范围内，则续期
//        if (differ <= properties.getDetect()) {
//            long renew = time + properties.getRenew();
//            redisUtils.expire(properties.getOnlineKey() + token, renew, TimeUnit.MILLISECONDS);
//        }
//    }
//
//    public String getToken(HttpServletRequest request) {
//        final String requestHeader = request.getHeader(properties.getHeader());
//        if (requestHeader != null && requestHeader.startsWith(properties.getTokenStartWith())) {
//            return requestHeader.substring(7);
//        }
//        return null;
//    }
//}
